/*
 * Copyright 2020-2021 redragon.dongbin
 *
 * This file is part of redragon-erp/赤龙ERP.

 * redragon-erp/赤龙ERP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.

 * redragon-erp/赤龙ERP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with redragon-erp/赤龙ERP.  If not, see <https://www.gnu.org/licenses/>.
 */
package com.erp.inv.output.controller;

import com.erp.common.inv.output.dao.model.InvOutputHeadCO;
import com.erp.dataset.service.DatasetCommonService;
import com.erp.hr.base.vo.ResultVO;
import com.erp.inv.output.dao.model.InvOutputLine;
import com.erp.inv.output.dao.model.InvOutputLineBase;
import com.erp.inv.output.dao.model.InvOutputLineCO;
import com.erp.inv.output.service.InvOutputLineService;
import com.erp.inv.outputeco.dao.model.InvOutputLineM;
import com.erp.inv.outputeco.service.InvOutputLineMService;
import com.erp.inv.outputeco.service.OutputEcoService;
import com.erp.inv.stock.service.InvStockService;
import com.erp.masterdata.common.service.MasterDataCommonService;
import com.erp.masterdata.material.dao.model.MdMaterial;
import com.erp.order.so.dao.model.SoLine;
import com.erp.order.so.dao.model.SoLineCO;
import com.erp.order.so.service.SoLineService;
import com.erp.prod.wip.dao.model.ProdWipTaskMaterial;
import com.erp.prod.wip.dao.model.ProdWipTaskMaterialCO;
import com.erp.prod.wip.service.ProdWipTaskMaterialService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.redragon.framework.hibernate.data.SnowFlake;
import org.redragon.framework.hibernate.model.Pages;
import org.redragon.framework.springmvc.ControllerSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/web/invOutputLine")
public class InvOutputLineWebController extends ControllerSupport{
    
    //日志处理
    private Logger logger = LoggerFactory.getLogger(InvOutputLineWebController.class);
    
    //服务层注入
    @Autowired
    private InvOutputLineService invOutputLineService;
    @Autowired
    private MasterDataCommonService masterDataCommonService;
    @Autowired
    private DatasetCommonService datasetCommonService;
    @Autowired
    private SoLineService soLineService;
    @Autowired
    private InvStockService invStockService;
    @Autowired
    private InvOutputLineMService invOutputLineMService;
    @Autowired
    private OutputEcoService outputEcoService;
    @Autowired
    private ProdWipTaskMaterialService prodWipTaskMaterialService;
    
    
    
    @Override
    public String getExceptionRedirectUrl() {
        return this.getFormatRedirectUrl("getInvOutputLineList");
    }
    
    
    
    /**
     * 
     * @description 查询数据列表
     * @date 2020-08-20 17:23:08
     * @author 
     * @param pages
     * @param invOutputLineCO
     * @param model
     * @return String
     *
     */
    @RequestMapping("getInvOutputLineList")
    public String getInvOutputLineList(Pages pages, InvOutputLineCO invOutputLineCO, String outputSourceType, Model model) {
        //分页查询数据
        if(pages.getPage()==0) {
            pages.setPage(1);
        }
        pages.setMax(100);
        
        //物料
        Map materialMap = this.masterDataCommonService.getMaterialMap();
        //物料单位
        Map materialUnitMap = this.datasetCommonService.getMaterialUnit();
        
        //分页查询数据
        List<InvOutputLineBase> invOutputLineList = new ArrayList<InvOutputLineBase>();
        //根据version请求参数，判断数据从原表获取还是变更表获取
        if(invOutputLineCO.getVersion()!=null&&invOutputLineCO.getVersion()>0) {
            InvOutputLineM invOutputLineM = new InvOutputLineM();
            invOutputLineM.setOutputHeadCode(invOutputLineCO.getOutputHeadCode());
            invOutputLineM.setVersion(invOutputLineCO.getVersion());
            List<InvOutputLineM> list = this.invOutputLineMService.getDataObjects(pages, invOutputLineM);
            for(InvOutputLineM obj: list) {
                invOutputLineList.add(obj);
            }
        }else {
            List<InvOutputLine> list = this.invOutputLineService.getInvOutputLineListByOutputHeadCode(pages, invOutputLineCO);
            for(InvOutputLine obj: list) {
                invOutputLineList.add(obj);
            }
        }
        
        for(InvOutputLineBase invOutputLine: invOutputLineList) {
            if(outputSourceType.equals("SO")&&StringUtils.isNotBlank(invOutputLine.getOutputSourceLineCode())) {
                SoLine soLine = this.soLineService.getDataObject(invOutputLine.getOutputSourceLineCode());
                invOutputLine.setMaterialCode(soLine.getMaterialCode());
                invOutputLine.setMaterialName(materialMap.get(soLine.getMaterialCode()).toString());
                invOutputLine.setSoPrice(soLine.getPrice());
                invOutputLine.setQuantity(soLine.getQuantity());
                invOutputLine.setSoUnit(materialUnitMap.get(soLine.getUnit()).toString());
                invOutputLine.setSoLineAmount(soLine.getAmount());
                //获取物料规格
                MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(soLine.getMaterialCode());
                invOutputLine.setMaterialStandard(mdMaterial.getStandard());
            }else {
                invOutputLine.setMaterialName(materialMap.get(invOutputLine.getMaterialCode()).toString());
                invOutputLine.setSoUnit(materialUnitMap.get(invOutputLine.getUnit()).toString());
                //获取物料规格
                MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(invOutputLine.getMaterialCode());
                invOutputLine.setMaterialStandard(mdMaterial.getStandard());
            }
            
        }
        
        //页面属性设置
        model.addAttribute("invOutputLineList", invOutputLineList);
        model.addAttribute("pages", pages);
        
        return "invOutput/tab/invOutputLineTab";
    }
    
    
    
    /**
     * 
     * @description 获取采购订单行选择框
     * @date 2020年7月20日
     * @author dongbin
     * @return
     * @return String
     *
     */
    @RequestMapping("getSelectSOLineModal")
    public String getSelectSOLineModal(Pages pages, SoLineCO soLineCO, InvOutputLineCO invOutputLineCO, InvOutputHeadCO invOutputHeadCO, Model model) {
        //分页查询数据
        if(pages.getPage()==0) {
            pages.setPage(1);
        }
        pages.setMax(1000);
        
        //分页查询采购订单行数据
        List<SoLine> soLineList = this.soLineService.getSoLineListBySoHeadCode(pages, soLineCO);
        
        //订单行获取已入库的数量
        if(invOutputHeadCO.getOutputSourceType().equals("SO")) {
            List<Object[]> listTemp = this.outputEcoService.getSoLineOutputQuantityBySoHead(soLineCO.getSoHeadCode());
            //循环设置采购订单入库数量
            for(SoLine soLine: soLineList) {
                //初始化入库数量
                soLine.setOutputQuantity(BigDecimal.ZERO);
                for(int a=0;a<listTemp.size();a++) {
                    Object[] obj = listTemp.get(a);
                    if(soLine.getSoLineCode().equals(String.valueOf(obj[0]))) {
                        soLine.setOutputQuantity(new BigDecimal(String.valueOf(obj[1])));
                        break;
                    }
                }
            }
        }
        
        //获取入库行数据
        Pages pagesTemp = new Pages();
        pagesTemp.setPage(1);
        pagesTemp.setMax(100);
        List<InvOutputLine> invOutputLineList = this.invOutputLineService.getInvOutputLineListByOutputHeadCode(pagesTemp, invOutputLineCO);
        
        //剔除已经做了入库行的采购订单行
        Iterator<SoLine> soLineIt = soLineList.iterator();
        while(soLineIt.hasNext()) {
            SoLine soLineTemp = soLineIt.next();
            
            //剔除非物料的采购订单行
            MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(soLineTemp.getMaterialCode());
            if(mdMaterial!=null&&mdMaterial.getMaterialType().equals("MATTER")) {
                soLineIt.remove();
            }
            
            //判断当前出库行是否存在此物料
            for(InvOutputLine invOutputLineTemp: invOutputLineList) {
                if(soLineTemp.getSoLineCode().equals(invOutputLineTemp.getOutputSourceLineCode())) {
                    soLineIt.remove();
                    break;
                }
            }
        }
        //重置总数据数量
        pages.setDataNumber(soLineList.size());
        
        //物料
        Map materialMap = this.masterDataCommonService.getMaterialMap();
        //物料单位
        Map materialUnitMap = this.datasetCommonService.getMaterialUnit();
        
        //页面属性设置
        model.addAttribute("soLineList", soLineList);
        model.addAttribute("pages", pages);
        model.addAttribute("materialMap", materialMap);
        model.addAttribute("materialUnitMap", materialUnitMap);
        
        return "invOutput/pop/selectSOLineModal";
    }
    
    
    
    /**
     * 
     * @description 查询单条数据
     * @date 2020-08-20 17:23:08
     * @author 
     * @param invOutputLine
     * @param model
     * @return String
     *
     */
    @RequestMapping("getInvOutputLine")
    public String getInvOutputLine(InvOutputLine invOutputLine, String outputType, String outputSourceType, String outputSourceHeadCode, String warehouseCode, Model model) {
        //物料
        Map materialMap = this.masterDataCommonService.getMaterialForMaterialMap();
        //物料单位
        Map materialUnitMap = this.datasetCommonService.getMaterialUnit();
        //生产任务物料需求数量
        Map prodMaterialQuantityMap = new HashMap<String, Double>();
        //生产任务物料需求行编码
        Map prodTaskMaterialLineMap = new HashMap<String, String>();
        
        //查询要编辑的数据
        if(invOutputLine!=null&&invOutputLine.getOutputLineId()!=null) {
            invOutputLine = this.invOutputLineService.getDataObject(invOutputLine.getOutputLineId());
            //根据来源获取单据数据
            if(StringUtils.isNotBlank(outputSourceType)) {
                if(outputSourceType.equals("SO")) {
                    SoLine soLine = this.soLineService.getDataObject(invOutputLine.getOutputSourceLineCode());
                    invOutputLine.setMaterialCode(soLine.getMaterialCode());
                    invOutputLine.setMaterialName(materialMap.get(soLine.getMaterialCode()).toString());
                    invOutputLine.setSoPrice(soLine.getPrice());
                    invOutputLine.setQuantity(soLine.getQuantity());
                    invOutputLine.setSoUnit(materialUnitMap.get(soLine.getUnit()).toString());
                    invOutputLine.setSoLineAmount(soLine.getAmount());
                    //获取物料规格
                    MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(soLine.getMaterialCode());
                    invOutputLine.setMaterialStandard(mdMaterial.getStandard());
                    
                    //获取销售订单行已出库数量
                    BigDecimal outputedQuantity = this.invOutputLineService.getOutputedQuantityBySoLine(invOutputLine.getOutputSourceLineCode(), invOutputLine.getOutputLineId());
                    invOutputLine.setOutputedQuantity(outputedQuantity);
                }else if(outputSourceType.equals("PROD")) {
                    if(outputType.equals("PROD_GET")) {
                        if(StringUtils.isNotBlank(outputSourceHeadCode)) {
                            Pages pages = new Pages();
                            pages.setMax(100);
                            pages.setPage(1);
                            ProdWipTaskMaterialCO prodWipTaskMaterialCO = new ProdWipTaskMaterialCO();
                            prodWipTaskMaterialCO.setTaskCode(outputSourceHeadCode);
                            //获取生产任务的物料需求
                            materialMap = new HashMap<String, String>(); 
                            List<ProdWipTaskMaterial> prodWipTaskMaterialList = this.prodWipTaskMaterialService.getWipTaskMaterialListByTaskCode(pages, prodWipTaskMaterialCO);
                            for(ProdWipTaskMaterial prodWipTaskMaterial: prodWipTaskMaterialList) {
                                materialMap.put(prodWipTaskMaterial.getMaterialCode(), this.masterDataCommonService.getMaterialForMaterialMap().get(prodWipTaskMaterial.getMaterialCode()));
                                prodMaterialQuantityMap.put(prodWipTaskMaterial.getMaterialCode(), prodWipTaskMaterial.getQuantity());
                                prodTaskMaterialLineMap.put(prodWipTaskMaterial.getMaterialCode(), prodWipTaskMaterial.getTaskMaterialCode());
                            }
                        }
                    }else if(outputType.equals("WIP_OUT")) {
                        materialMap = new HashMap<String, String>();
                        materialMap.put(invOutputLine.getMaterialCode(), this.masterDataCommonService.getMaterialForMaterialMap().get(invOutputLine.getMaterialCode()));
                    }
                }
            }
        }else {
            //新增
            //根据来源获取单据数据
            if(StringUtils.isNotBlank(outputSourceType)) {
                if(outputSourceType.equals("SO")) {
                    if(StringUtils.isNotBlank(invOutputLine.getMaterialCode())) {
                        //获取物料规格
                        MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(invOutputLine.getMaterialCode());
                        invOutputLine.setMaterialStandard(mdMaterial.getStandard());
                        
                        //获取销售订单行已出库数量
                        BigDecimal outputedQuantity = this.invOutputLineService.getOutputedQuantityBySoLine(invOutputLine.getOutputSourceLineCode(), 0);
                        invOutputLine.setOutputedQuantity(outputedQuantity);
                    }
                }else if(outputSourceType.equals("PROD")) {
                    if(StringUtils.isNotBlank(outputSourceHeadCode)) {
                        Pages pages = new Pages();
                        pages.setMax(100);
                        pages.setPage(1);
                        ProdWipTaskMaterialCO prodWipTaskMaterialCO = new ProdWipTaskMaterialCO();
                        prodWipTaskMaterialCO.setTaskCode(outputSourceHeadCode);
                        //获取生产任务的物料需求
                        List<ProdWipTaskMaterial> prodWipTaskMaterialList = this.prodWipTaskMaterialService.getWipTaskMaterialListByTaskCode(pages, prodWipTaskMaterialCO);
                        materialMap = new HashMap<String, String>(); 
                        for(ProdWipTaskMaterial prodWipTaskMaterial: prodWipTaskMaterialList) {
                            materialMap.put(prodWipTaskMaterial.getMaterialCode(), this.masterDataCommonService.getMaterialForMaterialMap().get(prodWipTaskMaterial.getMaterialCode()));
                            prodMaterialQuantityMap.put(prodWipTaskMaterial.getMaterialCode(), prodWipTaskMaterial.getQuantity());
                            prodTaskMaterialLineMap.put(prodWipTaskMaterial.getMaterialCode(), prodWipTaskMaterial.getTaskMaterialCode());
                        }
                    }
                }
            }    
              
        }
        
        //获取物料库存
        Double stockNumber = 0D;
        if(invOutputLine!=null&&StringUtils.isNotBlank(invOutputLine.getMaterialCode())) {
            stockNumber = this.invStockService.getStockNumberByMaterialCode(invOutputLine.getMaterialCode(), warehouseCode);
        }
        
        //页面属性设置
        model.addAttribute("invOutputLine", invOutputLine);
        model.addAttribute("stockNumber", stockNumber);
        model.addAttribute("materialMap", materialMap);
        model.addAttribute("materialUnitMap", materialUnitMap);
        model.addAttribute("prodMaterialQuantityMap", prodMaterialQuantityMap);
        model.addAttribute("prodTaskMaterialLineMap", prodTaskMaterialLineMap);
        
        return "invOutput/pop/addLineModal";
    }
    
    
    
    /**
     * 
     * @description 异步获取物料的库存数量
     * @date 2020年10月23日
     * @author dongbin
     * @param materialCode
     * @return
     * @return String
     *
     */
    @RequestMapping("getMaterialStockNumberAjax")
    @ResponseBody
    public String getMaterialStockNumberAjax(String materialCode, String warehouseCode) {
        //物料库存
        Double stockNumber = 0D;
        
        if(StringUtils.isNotBlank(materialCode)) {
            stockNumber = this.invStockService.getStockNumberByMaterialCode(materialCode, warehouseCode);
        }
        
        return "{\"stockNumber\":\""+stockNumber+"\"}";
    }
    
    
    
    /**
     * 
     * @description 编辑数据
     * @date 2020-08-20 17:23:08
     * @author 
     * @param invOutputLine
     * @param bindingResult
     * @param model
     * @return String
     *
     */
    @RequestMapping("editInvOutputLine")
    @ResponseBody
    public String editInvOutputLine(@Valid InvOutputLine invOutputLine, BindingResult bindingResult, Model model, RedirectAttributes attr) {
        try {
            /*
            //参数校验
            Map<String, String> errorMap = this.validateParameters(bindingResult, model);
            if(errorMap.size()>0) {
                return "forward:getInvInputLine";
            }
            */
            
            //对当前编辑的对象初始化默认的字段
            if(invOutputLine.getOutputLineId()==null) {
                invOutputLine.setOutputLineCode(SnowFlake.getConcurrentId().toString());
            }
            
            //保存编辑的数据
            this.invOutputLineService.insertOrUpdateDataObject(invOutputLine);
            
            return "{\"result\":\"success\"}";
        }catch(Exception e) {
            return "{\"result\":\"error\"}";
        }
    }
    
    
    
    /**
     * 
     * @description 删除数据
     * @date 2020-08-20 17:23:08
     * @author 
     * @param invOutputLine
     * @return String
     *
     */
    @RequestMapping("deleteInvOutputLine")
    @ResponseBody
    public String deleteInvOutputLine(InvOutputLine invOutputLine, RedirectAttributes attr) {
        try {
            //删除数据前验证数据
            if(invOutputLine!=null&&invOutputLine.getOutputLineId()!=null) {
                //删除数据
                this.invOutputLineService.deleteDataObject(invOutputLine);
            }
            
            return "{\"result\":\"success\"}";
        }catch(Exception e) {
            return "{\"result\":\"error\"}";
        }
    }

    /**
     * 新增/编辑
     * @param invOutputLine 需要新增/编辑的对象
     * @return 新增/编辑结果
     */
    @ResponseBody
    @RequestMapping("save")
    public ResultVO<String> save(@RequestBody InvOutputLine invOutputLine) {
        try {
            if(ObjectUtils.isNotEmpty(invOutputLine.getOutputLineId())){
                invOutputLineService.updateDataObject(invOutputLine);
            }else{
                invOutputLineService.insertDataObject(invOutputLine);
            }
            return ResultVO.success();
        }catch (Exception e){
            return ResultVO.error("修改失败!");
        }
    }

    /**
     * 删除
     * @param id 需要删除对象的id
     * @return 删除结果
     */
    @ResponseBody
    @RequestMapping("del")
    public ResultVO<String> del(Long id) {
        return invOutputLineService.delById(id);
    }


}
